package serializer

import (
	"time"

	"github.com/gin-gonic/gin"
)

// Response 基础序列化器
type Response struct {
	Status int         `json:"status"`
	Data   interface{} `json:"data,omitempty"`
	Msg    string      `json:"msg"`
	Error  string      `json:"error,omitempty"`
}

// DataList 基础列表结构
type DataList struct {
	Items interface{} `json:"items"`
	Total uint        `json:"total"`
}

// TaskDataList 基础列表结构
type TaskDataList struct {
	Items interface{} `json:"items"`
	Total uint        `json:"total"`
	Done  uint        `json:"done_total"`
	Rest  uint        `json:"rest_total"`
}

// TrackedErrorResponse 有追踪信息的错误响应
type TrackedErrorResponse struct {
	Response
	TrackID string `json:"track_id"`
}

// 三位数错误编码为复用http原本含义
// 五位数错误编码为应用自定义错误
// 五开头的五位数错误编码为服务器端错误，比如数据库操作失败
// 四开头的五位数错误编码为客户端错误，有时候是客户端代码写错了，有时候是用户操作错误
const (
	// CodeCheckLogin 未登录
	CodeCheckLogin = 401
	// CodeNoRightErr 未授权访问
	CodeNoRightErr = 403
	// CodeDBError 数据库操作失败
	CodeDBError = 50001
	// CodeEncryptError 加密失败
	CodeEncryptError = 50002
	//CodeParamErr 各种奇奇怪怪的参数错误
	CodeParamErr = 40001
)

// 处理serializer输出的时间
func serializerTime(timeInput *time.Time) string {
	var timeOutput string
	if timeInput != nil {
		timeOutput = timeInput.Format("2006-01-02 15:04:05")
	} else {
		timeOutput = ""
	}
	return timeOutput
}

// CheckLogin 检查登录
func CheckLogin() Response {
	return Response{
		Status: CodeCheckLogin,
		Msg:    "未登录",
	}
}

// BuildListResponse 列表构建器
func BuildListResponse(items interface{}, total uint) Response {
	return Response{
		Data: DataList{
			Items: items,
			Total: total,
		},
	}
}

// BuildTaskListResponse 列表构建器
func BuildTaskListResponse(items interface{}, total uint, done_total uint, rest_total uint) Response {
	return Response{
		Data: TaskDataList{
			Items: items,
			Total: total,
			Done:  done_total,
			Rest:  rest_total,
		},
	}
}

// BuildUploadFileResponse 文件上传序列化器
func BuildUploadFileResponse(file_url string) Response {
	return Response{
		Data:   file_url,
		Status: 0,
		Msg:    "",
	}
}

// Err 通用错误处理
func Err(errCode int, msg string, err error) Response {
	res := Response{
		Status: errCode,
		Msg:    msg,
	}
	// 生产环境隐藏底层报错
	if err != nil && gin.Mode() != gin.ReleaseMode {
		res.Error = err.Error()
	}
	return res
}

// DBErr 数据库操作失败
func DBErr(msg string, err error) Response {
	if msg == "" {
		msg = "数据库操作失败"
	}
	return Err(CodeDBError, msg, err)
}

// ParamErr 各种参数错误
func ParamErr(msg string, err error) Response {
	if msg == "" {
		msg = "参数错误"
	}
	return Err(CodeParamErr, msg, err)
}
